// -------------------------------------------------
// BlinKit - BlinKit Library
// -------------------------------------------------
//   File Name: web_page.cpp
// Description: WebPage Class
//      Author: Ziming Li
//     Created: 2022-05-01
// -------------------------------------------------
// Copyright (C) 2022 MingYang Software Technology.
// -------------------------------------------------

#include "./web_page.h"

#include "blinkit/blink/public/platform/web_layer_tree_view.h"
#include "blinkit/blink/renderer/bindings/core/script_controller.h"
#include "blinkit/blink/renderer/core/frame/local_frame.h"
#include "blinkit/blink/renderer/core/page/page.h"
#include "blinkit/ui/web_page_host.h"

namespace BlinKit {

WebPage::WebPage(WebPageHost *host) : m_host(host)
{
}

WebPage::~WebPage(void) = default;

void WebPage::ConvertViewportToWindow(IntRect *rect) const
{
    rect->scale(m_frame->pageZoomFactor());
}

void WebPage::DestroyPage(void)
{
    ASSERT(m_page);
    m_page->willBeDestroyed();
    m_page.reset();
}

void WebPage::dispatchDidFinishDocumentLoad(bool documentIsEmpty)
{
    ResumeTreeViewCommitsIfRenderingReady();
}

void WebPage::Initialize(const PageClients &pageClients, float scaleFactor)
{
    ASSERT(nullptr != m_host);
    ASSERT(nullptr == m_layerTreeView);
    m_layerTreeView = m_host->GetLayerTreeView();
    ASSERT(nullptr != m_layerTreeView);

    ASSERT(!m_page);
    m_page = Page::Create(pageClients);
    ASSERT(m_page);

    ASSERT(!m_frame);
    m_frame = LocalFrame::create(this, &m_page->frameHost(), scaleFactor);
    ASSERT(m_frame);
    OnFrameCreated(m_frame.get());

    m_frame->init();
}

void WebPage::PerformAnimation(double tick)
{
    ASSERT(isMainThread());

    if (!m_page)
        return;

    m_frame->script().ExecutePendingJobs();
    PageWidgetDelegate::animate(*m_page, tick);
    UpdateLifecycle();
}

WebInputEventResult WebPage::ProcessInput(const WebInputEvent &e)
{
    return PageWidgetDelegate::handleInputEvent(*this, e, m_frame.get());
}

void WebPage::ResumeTreeViewCommitsIfRenderingReady(void)
{
    if (!m_frame->loader().stateMachine()->committedFirstRealDocumentLoad())
        return;
    if (!m_frame->document()->isRenderingReady())
        return;

    m_layerTreeView->setDeferCommits(false);
    m_layerTreeView->setNeedsBeginFrame();
}

void WebPage::ScheduleAnimation(void)
{
    m_layerTreeView->setNeedsBeginFrame();
}

void WebPage::UpdateLifecycle(void)
{
    ASSERT(m_page);
    ASSERT(m_frame);
    PageWidgetDelegate::updateAllLifecyclePhases(*m_page, *m_frame);
}

} // namespace BlinKit
